home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1996 September / JCSM Shareware Collection (JCS Distribution) (September 1996).ISO / hutility / cdsndoff.zip / SOURCE.ZIP / SOUNDOFF.C < prev    next >
C/C++ Source or Header  |  1993-07-24  |  23KB  |  646 lines

  1. /***************************************************************************/
  2. /*                              CD SOUND OFF                               */
  3. /***************************************************************************/
  4. /*
  5.  
  6.     CD SoundOff is an audio CD player that is provided for your enjoyment.  
  7. If you like CD SoundOff, feel free to show me by helping with the 
  8. development costs.  Any and all donations will be greatly appreciated.
  9.  
  10.     CD SoundOff is provided as is with the C source code.  This software was 
  11. developed using the Microsoft Windows 3.1 SDK and Microsoft C 7.0.  Feel free 
  12. to add your own enhancements to CD SoundOff and please send me a copy
  13. so that I can keep up with all of the new and exciting CD bells and 
  14. whistles.  
  15.  
  16.                               NickleWare
  17.                               P.O. Box 393
  18.                               Orem, UT. 84059
  19.  
  20.  
  21.  
  22. NickleWare 
  23. CompuServe: 72730,1002
  24. Copyright (C) 93 Bradley Nicholes 
  25.  
  26. This documentation must accompany the CD SoundOff software. 
  27.  
  28. NickleWare or Bradley Nicholes shall not be liable for any damages, whether 
  29. direct, indirect, special or consequential arising from the use or failure 
  30. of this program to operate in the manner desired by the user.
  31.  
  32. */
  33.  
  34. /***************************************************************************/
  35. /*                      I N C L U D E   F I L E S                          */
  36. /***************************************************************************/
  37.  
  38. #define NOGDICAPMASKS
  39. #define NOVIRTUALKEYCODES
  40. #define NONCMESSAGES
  41. #define NODRAWFRAME
  42. #define NOKEYSTATE
  43. #define NORASTEROPS
  44.  
  45.  
  46. #include <WINDOWS.H>
  47. #include <mmsystem.h>
  48. #include "soundoff.h"
  49. #include <stdlib.h>
  50. #include <string.h>
  51.  
  52. /***************************************************************************/
  53. /*      T H E   P R O G R A M ' S   G L O B A L   V A R I A B L E S        */
  54. /***************************************************************************/
  55.  
  56. HINSTANCE hInst;
  57.  
  58. /***************************************************************************/
  59. /*                           FORWARD REFERENCES                            */
  60. /***************************************************************************/
  61.  
  62. BOOL CALLBACK SoundOffDlgProc (HWND, UINT, WPARAM, LPARAM);
  63. BOOL CALLBACK AboutboxWindowProc (HWND, UINT, WPARAM, LPARAM);
  64.  
  65. /***************************************************************************/
  66. /*                       M A I N   P R O G R A M                           */
  67. /***************************************************************************/
  68.  
  69.  
  70. int FAR PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
  71. HANDLE hInstance, hPrevInstance;
  72. LPSTR  lpszCmdLine;                       /*  Length of the command line.  */
  73. int    cmdShow;                           /*  Iconic or Tiled when start.  */
  74. {
  75.  
  76.    FARPROC  lpprocSoundOff;      
  77.    HWND  hwndDlg;
  78.    MSG   msg;
  79.  
  80.    hInst = hInstance;
  81.  
  82.    // Create the main dialog window as a modeless dialog.
  83.    lpprocSoundOff = (FARPROC)MakeProcInstance( SoundOffDlgProc, hInstance);
  84.    hwndDlg = CreateDialog (hInstance, "SoundOffDlg", GetDesktopWindow(), 
  85.       lpprocSoundOff);
  86.  
  87.    // If the dialog was created correctly then contine to the main message
  88.    //  loop.  Otherwise exit the program.
  89.    if (hwndDlg == 0)
  90.       return 1;
  91.  
  92.    while (GetMessage(&msg, NULL, 0, 0))          /*  The main loop:         */
  93.    {                                             /*  (terminated by a QUIT) */
  94.       if (!IsDialogMessage(hwndDlg, &msg))
  95.       {
  96.          TranslateMessage(&msg);              /*  Have Windows translate */
  97.          DispatchMessage(&msg);               /*  Have Windows give message */
  98.       }                                       /*  to the window proc.    */
  99.    }
  100.  
  101.    // Destroy the dialog and exit the program.
  102.    DestroyWindow (hwndDlg);
  103.    FreeProcInstance ( lpprocSoundOff);
  104.    return(0);
  105. }
  106.  
  107. /***************************************************************************/
  108. /*    T H E   A B O U T   B O X   H A N D L I N G   P R O C E D U R E      */
  109. /***************************************************************************/
  110.  
  111. /*   This is the window procedure for the main CD SoundOff control panel. */
  112.  
  113.  
  114. BOOL CALLBACK SoundOffDlgProc (HWND hDlg, UINT message, WPARAM wParam, 
  115.    LPARAM lParam)
  116. {
  117.  
  118.    DRAWITEMSTRUCT FAR *pDrawItem;   // Passed in from the WM_DRAWITEM message.
  119.    HICON    hIcon;                  // Button Icon.
  120.    char     szBuffer[128];          // CD Audio command buffer.
  121.    char     szReturn[128];          // CD Audio return buffer.
  122.    static BOOL bContinuous = FALSE; // Auto-Repeat flag.
  123.    static BOOL bPlay = FALSE;       // CD Audio currently playing flag.
  124.    static BOOL bPause = FALSE;      // CD Audio currently paused flag.
  125.    static WORD wTracks;             // Total number of tracks.
  126.    static WORD wCurrTrack;          // Currently playing track.
  127.    static HICON hTrackIcon;         // Track icon.
  128.    HICON    hOldIcon;               // Previous track icon.
  129.    PAINTSTRUCT ps;                  // Paint structure.
  130.    RECT rc;                         // Window rectangle structure.
  131.    HMENU hSysMenu;                  // System menu.
  132.    FARPROC  lpprocAbout;            // About dialog proc.
  133.  
  134.    switch (message ) {
  135.  
  136.       case WM_INITDIALOG:
  137.  
  138.          // Open the cdaudio device to query the current status.
  139.          mciSendString("open cdaudio", NULL, 0, hDlg);
  140.  
  141.          // Set the cdaudio device time format.
  142.          mciSendString("set cdaudio time format tmsf", NULL, 0, hDlg);
  143.  
  144.          // Query the current state of the device.
  145.          mciSendString("status cdaudio mode", szReturn, sizeof(szReturn), 
  146.             hDlg);
  147.  
  148.          // If the cdaudio device is playing then initiallize the status
  149.          //  to the current state.
  150.          if (_stricmp (szReturn, "playing") == 0) {
  151.  
  152.             bPlay = TRUE;
  153.  
  154.             // Tell the device to notify the dialog of any events.
  155.             mciSendString("play cdaudio notify", NULL, 0, hDlg);
  156.  
  157.             // Start the status polling timer.
  158.             SetTimer(hDlg, CD_TIMER, 500, NULL);
  159.          }
  160.  
  161.          // If the cdaudio device is paused then initialize the status to
  162.          //  the current state.
  163.          if (_stricmp (szReturn, "paused") == 0) {
  164.  
  165.             bPause = TRUE;
  166.          }
  167.  
  168.          // Load and display the default track indicator icon.
  169.          hTrackIcon = LoadIcon (hInst, "NONE");
  170.  
  171.          // Add the control panel commands to the system menu.
  172.          hSysMenu = GetSystemMenu (hDlg, FALSE);
  173.  
  174.          AppendMenu (hSysMenu, MF_SEPARATOR, 0, NULL);
  175.          AppendMenu (hSysMenu, MF_STRING, IDB_PREVIOUS, "Pre&vious");
  176.          AppendMenu (hSysMenu, MF_STRING, IDB_PLAY, "&Play");
  177.          AppendMenu (hSysMenu, MF_STRING, IDB_PAUSE, "P&ause");
  178.          AppendMenu (hSysMenu, MF_STRING, IDB_STOP, "S&top");
  179.          AppendMenu (hSysMenu, MF_STRING, IDB_NEXT, "&Next");
  180.          AppendMenu (hSysMenu, MF_STRING, IDB_CONTINUOUS, "A&uto-Repeat");
  181.          AppendMenu (hSysMenu, MF_SEPARATOR, 0, NULL);
  182.          AppendMenu (hSysMenu, MF_STRING, IDM_ABOUT, "About!");
  183.  
  184.          return TRUE;
  185.  
  186.       case WM_TIMER:
  187.  
  188.          // Query the cdaudio device for the current track.
  189.          mciSendString("status cdaudio current track", szReturn, 
  190.             sizeof(szReturn), hDlg);
  191.  
  192.          // If the current track has changed then update the display.
  193.          if (wCurrTrack != (WORD)atoi(szReturn)) {
  194.          
  195.             wCurrTrack = atoi(szReturn);
  196.  
  197.             // Load and display the new track display icon.
  198.             switch (wCurrTrack) {
  199.  
  200.                case 0:
  201.                   hTrackIcon = LoadIcon (hInst, "NONE");
  202.                   break;
  203.                case 1:
  204.                   hTrackIcon = LoadIcon (hInst, "ONE");
  205.                   break;
  206.                case 2:
  207.                   hTrackIcon = LoadIcon (hInst, "TWO");
  208.                   break;
  209.                case 3:
  210.                   hTrackIcon = LoadIcon (hInst, "THREE");
  211.                   break;
  212.                case 4:
  213.                   hTrackIcon = LoadIcon (hInst, "FOUR");
  214.                   break;
  215.                case 5:
  216.                   hTrackIcon = LoadIcon (hInst, "FIVE");
  217.                   break;
  218.                case 6:
  219.                   hTrackIcon = LoadIcon (hInst, "SIX");
  220.                   break;
  221.                case 7:
  222.                   hTrackIcon = LoadIcon (hInst, "SEVEN");
  223.                   break;
  224.                case 8:
  225.                   hTrackIcon = LoadIcon (hInst, "EIGHT");
  226.                   break;
  227.                case 9:
  228.                   hTrackIcon = LoadIcon (hInst, "NINE");
  229.                   break;
  230.                case 10:
  231.                   hTrackIcon = LoadIcon (hInst, "TEN");
  232.                   break;
  233.                case 11:
  234.                   hTrackIcon = LoadIcon (hInst, "ELEVEN");
  235.                   break;
  236.                case 12:
  237.                   hTrackIcon = LoadIcon (hInst, "TWELVE");
  238.                   break;
  239.                case 13:
  240.                   hTrackIcon = LoadIcon (hInst, "THIRTEEN");
  241.                   break;
  242.                case 14:
  243.                   hTrackIcon = LoadIcon (hInst, "FOURTEEN");
  244.                   break;
  245.                case 15:
  246.                   hTrackIcon = LoadIcon (hInst, "FIFTEEN");
  247.                   break;
  248.                case 16:
  249.                   hTrackIcon = LoadIcon (hInst, "SIXTEEN");
  250.                   break;
  251.                case 17:
  252.                   hTrackIcon = LoadIcon (hInst, "SEVENTEEN");
  253.                   break;
  254.                case 18:
  255.                   hTrackIcon = LoadIcon (hInst, "EIGHTEEN");
  256.                   break;
  257.                case 19:
  258.                   hTrackIcon = LoadIcon (hInst, "NINETEEN");
  259.                   break;
  260.                case 20:
  261.                   hTrackIcon = LoadIcon (hInst, "TWENTY");
  262.                   break;
  263.  
  264.             }
  265.  
  266.             // Display the new track icon and destroy the previous one.
  267.             hOldIcon = (HICON)SendDlgItemMessage (hDlg, IDS_TRACK, 
  268.                STM_SETICON, hTrackIcon, 0);
  269.             DestroyIcon (hOldIcon);
  270.  
  271.             // If the dialog is iconized then force the icon to repaint.
  272.             if (IsIconic(hDlg)) {
  273.  
  274.                InvalidateRect (hDlg, NULL, FALSE);
  275.             }
  276.          }
  277.          break;
  278.  
  279.       case MM_MCINOTIFY:
  280.          switch(wParam) {
  281.  
  282.             case MCI_NOTIFY_SUCCESSFUL:
  283.  
  284.                // Stop the cdaudio device after it has successfully played
  285.                //  through the entire CD and reset the state.
  286.                SendMessage (hDlg, WM_COMMAND, IDB_STOP, 0L);
  287.  
  288.                // If the auto-repeat flag is set the restart the device.
  289.                if (bContinuous) {
  290.  
  291.                   PostMessage (hDlg, WM_COMMAND, IDB_PLAY, 0L);
  292.                }
  293.                break;
  294.          }
  295.          break;
  296.  
  297.  
  298.       case WM_PAINT:
  299.          BeginPaint (hDlg, &ps);
  300.  
  301.          // Paint the dialog background with a dark gray.
  302.          FillRect (ps.hdc, &ps.rcPaint, GetStockObject(GRAY_BRUSH));
  303.  
  304.          // If the dialog is iconized then center the current track display
  305.          //  in the icon area.
  306.          if (IsIconic(hDlg)) {
  307.  
  308.             DrawIcon (ps.hdc, 2, 2, hTrackIcon);
  309.          }
  310.          EndPaint (hDlg, &ps);
  311.          return FALSE;
  312.  
  313.  
  314.       case WM_SYSCOMMAND:
  315.       case WM_COMMAND:
  316.  
  317.          switch(wParam) {
  318.  
  319.             case IDM_ABOUT:  
  320.  
  321.                // Display the about box as a modal dialog.
  322.                lpprocAbout = (FARPROC)MakeProcInstance (AboutboxWindowProc, 
  323.                   hInst);
  324.                DialogBox (hInst, "AboutBox", hDlg, lpprocAbout);
  325.                FreeProcInstance (lpprocAbout);
  326.                break;
  327.  
  328.             case IDB_PREVIOUS: 
  329.  
  330.                // if the cdaudio device is not stopped then seek to the
  331.                //  previous track.
  332.                if (bPlay) {
  333.  
  334.                   // Clear the paused flag
  335.                   bPause = FALSE;
  336.  
  337.                   // Force the pause button to repaint the new state.
  338.                   InvalidateRect (GetDlgItem (hDlg, IDB_PAUSE), NULL, FALSE);
  339.  
  340.                   // Get the current track and increment it by one.
  341.                   mciSendString("status cdaudio current track", szReturn, 
  342.                      sizeof(szReturn), hDlg);
  343.  
  344.                   // Seek to the previous track.
  345.                   _itoa (atoi(szReturn)-1, szReturn, 10);
  346.                   lstrcpy (szBuffer, "seek cdaudio to ");
  347.                   lstrcat (szBuffer, szReturn);
  348.                   mciSendString(szBuffer, NULL, 0, hDlg);
  349.  
  350.                   // Play the new track.
  351.                   mciSendString("play cdaudio notify", NULL, 0, hDlg);
  352.                }
  353.                return TRUE;
  354.  
  355.             case IDB_PLAY: 
  356.      
  357.                // If the cdaudio device is not playing or paused then start
  358.                //  playing the CD
  359.                if (!bPlay || bPause) {
  360.  
  361.                   // Set the state flags.
  362.                   bPlay = TRUE;
  363.                   bPause = FALSE;
  364.  
  365.                   // Force the buttons to display the new states.
  366.                   InvalidateRect (GetDlgItem (hDlg, IDB_PLAY), NULL, FALSE);
  367.                   InvalidateRect (GetDlgItem (hDlg, IDB_PAUSE), NULL, FALSE);
  368.  
  369.                   // If the device is not paused then open it, set the time
  370.                   //  format and query the number of tracks on the CD.
  371.                   if (!bPause) {
  372.                      mciSendString("open cdaudio", NULL, 0, hDlg);
  373.                      mciSendString("set cdaudio time format tmsf", NULL, 0, hDlg);
  374.                      mciSendString("status cdaudio number of tracks", 
  375.                         szReturn, sizeof(szReturn), hDlg);
  376.                      wTracks = (WORD)atoi(szReturn);
  377.                   }
  378.  
  379.                   // Start playing the CD
  380.                   mciSendString("play cdaudio notify", NULL, 0, hDlg);
  381.  
  382.                   // Start the status polling timer.
  383.                   SetTimer(hDlg, CD_TIMER, 500, NULL);
  384.  
  385.                }
  386.                return TRUE;
  387.  
  388.             case IDB_PAUSE: 
  389.  
  390.                // if the cdaudio device is not stopped then seek to the
  391.                //  previous track.
  392.                if (bPlay) {
  393.  
  394.                   // Set the state flags.
  395.                   bPause = TRUE;
  396.  
  397.                   // Force the buttons to display the new states.
  398.                   InvalidateRect (GetDlgItem (hDlg, IDB_PAUSE), NULL, FALSE);
  399.  
  400.                   // Pause the cdaudio device.
  401.                   mciSendString("pause cdaudio", NULL, 0, hDlg);
  402.                }
  403.                return TRUE;
  404.  
  405.             case IDB_STOP:      
  406.  
  407.                // if the cdaudio device is not stopped then seek to the
  408.                //  previous track.
  409.                if (bPlay) {
  410.  
  411.                   // Set the state flags.
  412.                   bPlay = FALSE;
  413.                   bPause = FALSE;
  414.  
  415.                   // Force the buttons to display the new states.
  416.                   InvalidateRect (GetDlgItem (hDlg, IDB_PLAY), NULL, FALSE);
  417.                   InvalidateRect (GetDlgItem (hDlg, IDB_PAUSE), NULL, FALSE);
  418.  
  419.                   // Stop and close the cdaudio device.
  420.                   mciSendString("stop cdaudio", NULL, 0, hDlg);
  421.                   mciSendString("close cdaudio", NULL, 0, hDlg);
  422.  
  423.                   // Kill the status polling timer.
  424.                   KillTimer (hDlg, CD_TIMER);
  425.                }
  426.                return TRUE;
  427.  
  428.             case IDB_NEXT:      
  429.  
  430.                // if the cdaudio device is not stopped then seek to the
  431.                //  previous track.
  432.                if (bPlay) {
  433.  
  434.                   // Set the state flags.
  435.                   bPause = FALSE;
  436.  
  437.                   // Force the buttons to display the new states.
  438.                   InvalidateRect (GetDlgItem (hDlg, IDB_PAUSE), NULL, FALSE);
  439.  
  440.                   // Get the current track and decrement it by one.
  441.                   mciSendString("status cdaudio current track", szReturn, 
  442.                      sizeof(szReturn), hDlg);
  443.  
  444.                   // Seek to the next track.
  445.                   _itoa (atoi(szReturn)+1, szReturn, 10);
  446.                   lstrcpy (szBuffer, "seek cdaudio to ");
  447.                   lstrcat (szBuffer, szReturn);
  448.                   mciSendString(szBuffer, NULL, 0, hDlg);
  449.  
  450.                   // Play the new track.
  451.                   mciSendString("play cdaudio notify", NULL, 0, hDlg);
  452.                }
  453.                return TRUE;
  454.  
  455.             case IDB_CONTINUOUS:
  456.  
  457.                // Set the state flags.
  458.                bContinuous = !bContinuous;
  459.  
  460.                // Force the buttons to display the new states.
  461.                InvalidateRect (GetDlgItem (hDlg, IDB_CONTINUOUS), NULL, FALSE);
  462.  
  463.                CheckMenuItem (GetSystemMenu (hDlg, FALSE), IDB_CONTINUOUS, 
  464.                   MF_BYCOMMAND | (bContinuous ? MF_CHECKED : MF_UNCHECKED));
  465.                return TRUE;
  466.  
  467.          }
  468.          break;
  469.  
  470.       case WM_DRAWITEM:
  471.  
  472.          // Get the draw item information.
  473.          pDrawItem = (DRAWITEMSTRUCT FAR*)lParam;
  474.  
  475.          CopyRect (&rc, &pDrawItem->rcItem);
  476.          rc.top = rc.bottom - 3;
  477.          FillRect (pDrawItem->hDC, &rc, GetStockObject(GRAY_BRUSH));
  478.  
  479.          // Don't do anything on a focus change.
  480.          if (pDrawItem->itemAction & ODA_FOCUS)
  481.             return FALSE;
  482.  
  483.          // Load and display the current state icon of the appropriate button.
  484.          switch(wParam) {
  485.  
  486.             case IDB_PREVIOUS:  
  487.  
  488.                // If the button is selected then load the pressed icon
  489.                //  Otherwise load the non-pressed icon.
  490.                if (pDrawItem->itemState & ODS_SELECTED) {
  491.  
  492.                   hIcon = LoadIcon (hInst, "PREVIN");
  493.                }
  494.                else {
  495.  
  496.                   hIcon = LoadIcon (hInst, "PREVOUT");
  497.                }
  498.                break;
  499.  
  500.             case IDB_PLAY:      
  501.  
  502.                // If the button is selected then load the pressed icon
  503.                //  Otherwise load the non-pressed icon.
  504.                if (pDrawItem->itemState & ODS_SELECTED) {
  505.  
  506.                   hIcon = LoadIcon (hInst, "PLAYIN");
  507.                }
  508.                else {
  509.  
  510.                   if (bPlay)
  511.                      hIcon = LoadIcon (hInst, "PLAYON");
  512.                   else 
  513.                      hIcon = LoadIcon (hInst, "PLAYOUT");
  514.                }
  515.                break;
  516.  
  517.             case IDB_PAUSE:     
  518.  
  519.                // If the button is selected then load the pressed icon
  520.                //  Otherwise load the non-pressed icon.
  521.                if (pDrawItem->itemState & ODS_SELECTED) {
  522.  
  523.                   hIcon = LoadIcon (hInst, "PAUSEIN");
  524.                }
  525.                else {
  526.  
  527.                   if (bPause)
  528.                      hIcon = LoadIcon (hInst, "PAUSEON");
  529.                   else 
  530.                      hIcon = LoadIcon (hInst, "PAUSEOUT");
  531.                }
  532.                break;
  533.  
  534.             case IDB_STOP:      
  535.  
  536.                // If the button is selected then load the pressed icon
  537.                //  Otherwise load the non-pressed icon.
  538.                if (pDrawItem->itemState & ODS_SELECTED) {
  539.  
  540.                   hIcon = LoadIcon (hInst, "STOPIN");
  541.                }
  542.                else {
  543.  
  544.                   hIcon = LoadIcon (hInst, "STOPOUT");
  545.                }
  546.                break;
  547.  
  548.             case IDB_NEXT:      
  549.  
  550.                // If the button is selected then load the pressed icon
  551.                //  Otherwise load the non-pressed icon.
  552.                if (pDrawItem->itemState & ODS_SELECTED) {
  553.  
  554.                   hIcon = LoadIcon (hInst, "NEXTIN");
  555.                }
  556.                else {
  557.  
  558.                   hIcon = LoadIcon (hInst, "NEXTOUT");
  559.                }
  560.                break;
  561.  
  562.             case IDB_CONTINUOUS:
  563.  
  564.                // If the button is selected then load the pressed icon
  565.                //  Otherwise load the non-pressed icon.
  566.                if (pDrawItem->itemState & ODS_SELECTED) {
  567.  
  568.                   hIcon = LoadIcon (hInst, "CONTIIN");
  569.                }
  570.                else {
  571.  
  572.                   // If the auto-repeat flag is set then load the 
  573.                   //  appropriate icon.
  574.                   if (bContinuous)
  575.                      hIcon = LoadIcon (hInst, "CONTINON");
  576.                   else 
  577.                      hIcon = LoadIcon (hInst, "CONTIOUT");
  578.                }
  579.                break;
  580.  
  581.          }
  582.  
  583.          // Display the new state icon and destroy the old one.
  584.          DrawIcon (pDrawItem->hDC, pDrawItem->rcItem.left, 
  585.             pDrawItem->rcItem.top, hIcon);
  586.          DestroyIcon (hIcon);
  587.          return TRUE;
  588.  
  589.       case WM_MEASUREITEM:
  590.          break;
  591.  
  592.       case WM_CLOSE:
  593.  
  594.          // Post a quit message to close the application.
  595.          PostQuitMessage (0);
  596.          break;
  597.    }
  598.  
  599.    return FALSE;
  600. }
  601.  
  602. /***************************************************************************/
  603. /*    T H E   A B O U T   B O X   H A N D L I N G   P R O C E D U R E      */
  604. /***************************************************************************/
  605.  
  606. /*   (This is the window procedure for the About dialog box.)              */
  607.  
  608.  
  609. static char SndOffInfo[] = 
  610.  
  611. "    CD SoundOff is an audio CD player that is provided for your enjoyment. \
  612. If you like CD SoundOff, feel free to show me by helping with the \
  613. development costs.  Any and all donations will be greatly appreciated.\
  614.   CD SoundOff is provided as is with the C source code.  This software was \
  615. developed using the Microsoft Windows 3.1 SDK and Microsoft C 7.0.  Feel free \
  616. to add your own enhancements to CD SoundOff and please send me a copy \
  617. so that I can keep up with all of the new and exciting CD bells and \
  618. whistles.  The documentation and source must accompany the CD SoundOff \
  619. software.";
  620.  
  621.  
  622. BOOL CALLBACK AboutboxWindowProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  623. {
  624.  
  625.    switch (message) {
  626.  
  627.       case WM_INITDIALOG:
  628.          SetDlgItemText (hDlg, ID_INFO, SndOffInfo);
  629.          return TRUE;
  630.  
  631.       case WM_COMMAND:
  632.          if (wParam == IDOK) {
  633.  
  634.             EndDialog (hDlg, TRUE);
  635.             return TRUE;
  636.          }
  637.          break;
  638.     }
  639.  
  640.     return FALSE;
  641. }
  642.  
  643.  
  644.  
  645.  
  646.